﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Crude.Core.Repository;
using Crude.Common;
using Crude.Core;
using System.IO;

namespace Crude.VisualStudioAddin.Forms
{
    public partial class ProjectsSettingsEditorForm : Form
    {
        public class ProjectSettingsViewModel
        {
            public bool IsCrude { get; set; }
            public string Name { get; set; }
            public string Version { get; set; }
            public string Description { get; set; }

            public EnvDTE.Project VSProject { get; set; }
        }

        EnvDTE80.DTE2 m_applicationObject;
        IList<ProjectSettingsViewModel> m_projectViewModels = new List<ProjectSettingsViewModel>();

        public ProjectsSettingsEditorForm(EnvDTE80.DTE2 applicationObject)
        {
            InitializeComponent();
            m_applicationObject = applicationObject;
        }

        private void ProjectsSettingsEditor_Load(object sender, EventArgs e)
        {
            dataGridView1.AutoGenerateColumns = false;

            foreach (EnvDTE.Project vsProject in m_applicationObject.Solution.Projects)
            {
                if (!string.IsNullOrEmpty(vsProject.FullName))
                {
                    Crude.Core.Project crudeProject = new Core.Project(vsProject.FullName);

                    ProjectObjectModel pom = null;

                    if (File.Exists(crudeProject.PomFilePath))
                    {
                        pom = new ProjectObjectModelLoader(crudeProject.PomFilePath).Load();
                    }

                    ProjectSettingsViewModel viewModel = new ProjectSettingsViewModel();
                    viewModel.Name = vsProject.Name;
                    viewModel.VSProject = vsProject;


                    if (pom != null)
                    {
                        viewModel.Version = pom.Version;
                        viewModel.Description = pom.Description;
                        viewModel.IsCrude = true;
                    }
                    else
                    {
                        viewModel.Version = crudeProject.GetProjectVersion();
                        viewModel.Description = crudeProject.GetProjectDescription();
                        viewModel.IsCrude = false;
                    }

                    m_projectViewModels.Add(viewModel);
                }
            }

            dataGridView1.DataSource = m_projectViewModels;
        }

        private void m_okButton_Click(object sender, EventArgs e)
        {
            foreach (ProjectSettingsViewModel viewModel in m_projectViewModels)
            {
                Crude.Core.Project crudeProject = new Core.Project(viewModel.VSProject.FullName);

                if (viewModel.IsCrude && File.Exists(crudeProject.PomFilePath))
                {
                    ProjectObjectModel pom = null;

                    pom = new ProjectObjectModelLoader(crudeProject.PomFilePath).Load();

                    if (viewModel.Description != pom.Description || viewModel.Version != pom.Version)
                    {
                        pom.Version = viewModel.Version;
                        pom.Description = viewModel.Description;

                        if (!m_applicationObject.SourceControl.IsItemUnderSCC(crudeProject.PomFilePath) ||
                            m_applicationObject.SourceControl.IsItemCheckedOut(crudeProject.PomFilePath) ||
                            m_applicationObject.SourceControl.CheckOutItem(crudeProject.PomFilePath))
                        {
                            ProjectObjectModelSaver projectObjectModelSaver = new ProjectObjectModelSaver();
                            projectObjectModelSaver.Save(crudeProject.PomFilePath, pom);
                        }
                    }
                }

                if (viewModel.Description != crudeProject.GetProjectDescription() ||
                    viewModel.Version != crudeProject.GetProjectVersion())
                {
                    string assemblyInfoFile = string.Format("{0}\\Properties\\AssemblyInfo.cs", crudeProject.ProjectDirectory);

                    if (!m_applicationObject.SourceControl.IsItemUnderSCC(assemblyInfoFile) ||
                           m_applicationObject.SourceControl.IsItemCheckedOut(assemblyInfoFile) ||
                           m_applicationObject.SourceControl.CheckOutItem(assemblyInfoFile))
                    {
                        string fileContent = "";

                        using (FileStream fileStream = new FileStream(assemblyInfoFile, FileMode.Open))
                        {
                            using (StreamReader streamReader = new StreamReader(fileStream))
                            {
                                fileContent = streamReader.ReadToEnd();                                
                            }
                            fileStream.Close();
                        }

                        fileContent = ReplaceProperty(crudeProject, fileContent,
                            "AssemblyDescription", crudeProject.GetProjectDescription(), viewModel.Description);

                        fileContent = ReplaceProperty(crudeProject, fileContent,
                            "AssemblyVersion", crudeProject.GetProjectVersion(), viewModel.Version);

                        fileContent = ReplaceProperty(crudeProject, fileContent,
                            "AssemblyFileVersion", crudeProject.GetProjectVersion(), viewModel.Version);


                        using (FileStream fileStream = new FileStream(assemblyInfoFile, FileMode.Create))
                        {
                            using (StreamWriter streamWriter = new StreamWriter(fileStream))
                            {
                                streamWriter.Write(fileContent);
                            }
                            fileStream.Close();
                        }
                    }
                }
            }

            Close();
        }

        private string ReplaceProperty(Crude.Core.Project crudeProject, string fileContent, 
            string property, string oldValue, string newValue)
        {
            string oldText = string.Format("[assembly: {0}(\"{1}\")]",property, oldValue);

            if (fileContent.Contains(oldText))
            {
                fileContent = fileContent.Replace(oldText,
                    string.Format("[assembly: {0}(\"{1}\")]",property, newValue));
            }
            else
            {
                fileContent += string.Format("[assembly: {0}(\"{1}\")]\r\n", property, newValue);
            }
            return fileContent;
        }

        private void m_cancelButton_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}
